package ca.cbc.medialib.dao;

import java.util.List;

import org.hibernate.criterion.Restrictions;

import ca.cbc.medialib.entity.Category;
import ca.cbc.medialib.entity.Media;

public class CategoryDAO extends EntityDAO<Category> {
	@Override
	public String getFullClassName() {
		return Category.class.getCanonicalName();
	}
	
	public Category findByFullTitle(String fullTitle) {
        return super.findByField("fullTitle", fullTitle);
	}
	
	@Override
	public void save(Category category) {
		Category parent = category.getParent();
        if (parent != null) {
        	if(findById(parent.getId()) == null) {
        		save(parent);
        	} else {
        		merge(parent);
        	}
        }
        super.save(category);	
	}
	
	@SuppressWarnings("unchecked")
	public List<Category> listParents() {
		return this.getCurrentSession().createCriteria(Category.class).add(Restrictions.isNull("parent")).list();
	}
	
	@Override
	public Category merge(Category category) {
		Category parent = category.getParent();
        if (parent != null) {
        	if(findById(parent.getId()) == null) {
        		save(parent);
        	} else {
        		merge(parent);
        	}
        } 
        
        //when use merge, hibernate will try to merge it's children, it not all children are in db, so some of children cannot be merged.
        category.removeAllChildren();
        category.removeAllMedias();
        return super.merge(category);	
	}
	
	public void delete(Category cat, Media media) {	
		Category parent = cat.getParent();
        if(parent != null){
        	parent.removeChild(cat);
        	/**
        	 * if parent and child refer to the same media is going to delete
        	 */
        	boolean hasMedia = true;
        	if(parent.getMedias().size() == 0 || (parent.getMedias().size() == 1 && parent.getMedias().get(0).equals(media))){
        		hasMedia = false;
        	}
        	
        	if(parent.getChildren().size() == 0 && !hasMedia){
        		delete(parent, media);
        	}
        }
        super.delete(cat);
	}
}
